﻿#region Using directives

using System;
using System.Collections.Generic;
using System.Text;

#endregion

namespace Weazel.Badger.Vhdl.Types
{
//  public abstract class EnumerationType : VhdlType
//  {
//    private string name;
//    public string Name
//    {
//      get
//      {
//        return name;
//      }
//
//      set
//      {
//        name = value;
//      }
//    }
//
//    public override Vhdl.Type[] PossibleConversions
//    {
//      get
//      {
//        return new Vhdl.Type[0];
//      }
//    }
//
//    public EnumerationType(string name) : base(Vhdl.Type.Enumeration | Vhdl.Type.UserDefined)
//    {
//      this.name = name;      
//    }
//
//    public EnumerationType(string name, Vhdl.Type type) : base(Vhdl.Type.Enumeration | type)
//    {
//      this.name = name;      
//    }
//  }

  public class LitteralBasedEnumerationType : Vhdl.Type, ITypeDeclaration
  {
    private List<string> identifiers = new List<string>();

    public string[] Members   
    {
      get
      {
        string[] r = new string[identifiers.Count];
        identifiers.CopyTo(r);
        return r;
      }
    }

    public LitteralBasedEnumerationType(string name) : base(name)
    {
    }

    public LitteralBasedEnumerationType(string name, string[] identifers) : base(name)
    {
      foreach (string i in identifiers)
        AddTypeMember(i);
    }

    public bool ContainsMember(string identifier)
    {
      return identifiers.Contains(identifier);
    }

    public void AddTypeMember(string identifier)
    {
      if (identifiers.Contains(identifier))
        throw new Exception("identifier already defined");

      identifiers.Add(identifier);
    }

    public override string ToString()
    {
      return Name;
    }

 
    public void Write(System.CodeDom.Compiler.IndentedTextWriter writer)
    {
      writer.WriteLine(string.Format("type {0} is (", Name));
      writer.Indent++;

      // enum type must have atleast one member ..
      System.Diagnostics.Debug.Assert(identifiers.Count > 0);

      for (int i = 0; i < identifiers.Count - 1; i++)
        writer.WriteLine(identifiers[i] + ", ");

      // no ending comma for last member
      writer.WriteLine(identifiers[identifiers.Count - 1]);

      writer.Indent--;
      writer.WriteLine(");");
    }
  }

  public class CharacterBasedEnumerationType : Vhdl.Type
  {
    private string[] characters;

    public CharacterBasedEnumerationType(string name, string[] characters) : base(name)
    {
      this.characters = characters;
    }

    public CharacterBasedEnumerationType(string name, string[] characters, Vhdl.Type type) :  // base(name, type)
      base(name, new TypePropertyInfo[]{new EnumerationProperty(type)})
    {
      this.characters = characters;
    }

    /*
    public override bool ImplicitConversionExists(VhdlTypeValue value)
    {
      if (value.Type is CharacterType)
      {
        for (int i = 0; i < characters.Length; i++)
          if (characters[i] == value.Value)
            return true;
      }

      return false;
    }
    */

//    public override bool CanConvertTo(Vhdl.Type type, ref bool isImplicit)
//    {
//      isImplicit = false;
//      return false;
//    }
  }
}
